package com.mzj.saas.commons.util;

public class BcdUtils
{
	private static final char[] bcdChars = "0123456789*#abc".toCharArray() ;
	private static final byte[] bcdBytes = new byte[256] ;
	private static final ThreadLocal<StringBuilder> bcdStrBufferHolder = new ThreadLocal<StringBuilder>() ;
	static
	{
		for( int i=0; i<bcdChars.length; i++ )
			bcdBytes[(byte)bcdChars[i]] = (byte)i ;
	}
	
	public static final byte[] decode( String str )
	{
		if( str == null || str.length() <= 0 )
			return null ;
		
		char[] arr = str.toCharArray() ;
		int clen = arr.length ;
		byte[] octs = new byte[(clen+1)/2] ;
		
		for( int i=0; i<octs.length; i++ )
		{
			int idx = 2*i ;
			byte oct1 = bcdBytes[arr[idx]] ;
			idx ++ ;
			if( idx == clen )
				octs[i] = (byte)(0xF0+oct1) ;
			else
			{
				int oct = bcdBytes[arr[idx]] ;
				oct <<= 4 ;
				oct += oct1 ;
				octs[i] = (byte)(0xFF&oct) ;
			}
		}
		
		return octs ;
	}

	public static final byte[] decode( String str, int len )
	{
		if( str == null || str.length() <= 0 )
			return null ;
		
		char[] arr = str.toCharArray() ;
		int clen = arr.length ;
		int blen = (clen+1)/2 ;
		byte[] octs = new byte[Math.max(blen, len)] ;
		
		for( int i=0; i<blen; i++ )
		{
			int idx = 2*i ;
			byte oct1 = bcdBytes[arr[idx]] ;
			idx ++ ;
			if( idx == clen )
				octs[i] = (byte)(0xF0+oct1) ;
			else
			{
				int oct = bcdBytes[arr[idx]] ;
				oct <<= 4 ;
				oct += oct1 ;
				octs[i] = (byte)(0xFF&oct) ;
			}
		}
		
		for( int i=blen; i<len; i++ )
			octs[i] = (byte)0xFF ;
		
		return octs ;
	}
	
	public static final String encode( byte[] arr )
	{
		if( arr == null || arr.length <= 0 )
			return null ;
		
		StringBuilder buf = bcdStrBufferHolder.get() ;
		if( buf == null )
		{
			buf = new StringBuilder() ;
			bcdStrBufferHolder.set(buf);
		}
		else
			buf.delete(0, buf.length()) ;
		
		for( byte oct:arr )
		{
			int idx = oct&0xF ;
			if( idx==0xF )
				break ;
			buf.append( bcdChars[idx] ) ;
			idx = (oct>>4)&0xF ;
			if( idx == 0xF )
				break ;
			buf.append( bcdChars[idx] ) ;
		}
		
		return buf.toString() ;
	}
}
